package com.nextive.weightlogger.dto;

import java.util.Calendar;

import com.nextive.weightlogger.WeightUnit;
import com.nextive.weightlogger.util.DateUtil;

/**
 * Represents a weight entered by the user and the time and date he weighted
 * himself.
 * 
 * This class uses grams internally to store the weight and it provides methods
 * to set and retrieve the weight expressed in any WeightUnit. It also provides
 * methods to retrieve human-friendly string representations of its fields.
 * 
 * @author Federico Baseggio <fedebaseggio@gmail.com>
 */
public class WeightEntry {
	/**
	 * The unique identifier of the entry.
	 */
	private Long id;
	
	/**
	 * The weight expressed in grams.
	 */
	private Float weightGrams;
	
	/**
	 * The time and date of the entry.
	 */
	private Calendar dateTime;
	
	/**
	 * Default constructor.
	 */
	public WeightEntry()
	{
	}

	/**
	 * Sets the unique identifier of the entry.
	 * 
	 * @return The unique identifier of the entry.
	 */
	public Long getId() {
		return id;
	}
	
	/**
	 * Sets the unique identifier of the entry.
	 * 
	 * @param id The unique identifier of the entry.
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Gets the weight in grams.
	 * 
	 * @return The weight expressed in grams.
	 */
	public Float getWeightGrams() {
		return weightGrams;
	}

	/**
	 * Sets the weight in grams.
	 * 
	 * @param grams The weight expressed in grams.
	 */
	public void setWeightGrams(Float grams) {
		this.weightGrams = grams;
	}
	
	/**
	 * Sets the date and time of the entry.
	 * 
	 * @param dateTime
	 *            A Calendar instance that represents the date and time of the
	 *            entry.
	 */
	public void setDateTime(Calendar dateTime) {
		this.dateTime = dateTime;
	}

	/**
	 * Gets the Calendar instance that represents the date and time of the
	 * entry.
	 * 
	 * @return The Calendar instance that represents the date and time of the
	 *         entry.
	 */
	public Calendar getDateTime() {
		return dateTime;
	}

	/**
	 * Gets the weight expressed in the specified unit.
	 * 
	 * @param unit
	 *            The unit used to convert the weight from unit used internally.
	 * @return The weight expressed in the specified unit.
	 */
	public Float getWeight(WeightUnit unit)
	{
		if (weightGrams == null)
		{
			return null;
		}
		return unit.valueFromGrams(weightGrams);
	}
	
	/**
	 * Sets the weight.
	 * 
	 * @param weight
	 *            The weight expressed in the specified unit.
	 * @param unit
	 *            The unit used to convert the weight to the unit used
	 *            internally.
	 */
	public void setWeight(Float weight, WeightUnit unit)
	{
		weightGrams = unit.toGrams(weight);
	}
	
	/**
	 * Returns a human-friendly string representation of the weight expressed in
	 * the specified unit.
	 * 
	 * @param unit
	 *            The weight unit to use for display.
	 * @return The weight expressed in the specified unit followed by the unit
	 *         symbol.
	 */
	public String getWeightForDisplay(WeightUnit unit)
	{
		return String.format("%1$.1f %2$s", getWeight(unit), unit.getSymbol());
	}
	
	/**
	 * Returns a human-friendly string representation of the entry date.
	 * 
	 * @return A human-friendly string representation of the entry date.
	 */
	public String getDateForDisplay()
	{
		return DateUtil.getFormattedDate(getDateTime());
	}
	
	/**
	 * Returns a human-friendly string representation of the entry time.
	 * 
	 * @return A human-friendly string representation of the entry time.
	 */
	public String getTimeForDisplay()
	{
		return DateUtil.getFormattedTime(getDateTime());
	}
}
